package com.xmut.mall.auth.aop;

import com.auth0.jwt.exceptions.InvalidClaimException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;

import com.xmut.mall.auth.annotation.CheckJwt;
import com.xmut.mall.auth.utils.JWTUtils;
import com.xmut.mall.auth.utils.RespBean;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Aspect
@Component
@Slf4j
public class CheckJwtAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private HttpServletResponse response;

    private DecodedJWT decodedJWT = null;

    @Around("@annotation(checkJwt)")
    public RespBean checkJwtAdvice(ProceedingJoinPoint point, CheckJwt checkJwt) {

        RespBean respBean = new RespBean();
        try {
            String accessToken = request.getHeader("accessToken");
            if (JWTUtils.checkIsExpires(accessToken) == false) {
                decodedJWT = JWTUtils.verifyToken(accessToken);
                request.setAttribute("userInfo", decodedJWT.getClaim("info").asString());
            } else if (JWTUtils.checkIsExpires(accessToken) == true) {
                String refreshToken = request.getHeader("refreshToken");
                decodedJWT = JWTUtils.verifyToken(refreshToken);
                String info = decodedJWT.getClaim("info").asString();
                String newAccessToken = JWTUtils.createAccessToken(info);
                String newRefreshToken = JWTUtils.createRefreshToken(info);
                request.setAttribute("newAccessToken", newAccessToken);
                request.setAttribute("newRefreshToken", newRefreshToken);
                response.addHeader("Access-Control-Expose-Headers", "accessToken");
                response.addHeader("Access-Control-Expose-Headers", "refreshToken");
                response.addHeader("accessToken", newAccessToken);
                response.addHeader("refreshToken", newRefreshToken);
                log.info("jwt进行续签");
            }
            respBean = (RespBean) point.proceed();
        } catch (JWTDecodeException e) {
            respBean.setMessage("token解码异常");
        } catch (InvalidClaimException e) {
            respBean.setMessage("token荷载验证异常");
        } catch (TokenExpiredException e) {
            respBean.setMessage("token已过期,请重新登录");
        } catch (Throwable e) {
            e.printStackTrace();
            respBean.setMessage("token无效");
        }
        return respBean;
    }

}
